/**************************************************************************************** 
 Copyright © 2003-2012 ZTEsoft Corporation. All rights reserved. Reproduction or       <br>
 transmission in whole or in part, in any form or by any means, electronic, mechanical <br>
 or otherwise, is prohibited without the prior written consent of the copyright owner. <br>
 ****************************************************************************************/
package com.iwhalecloud.bss.kite.cucc.web.controller.scene;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.client.api.scene.operate.IOperateSceneFuncProdInstService;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneAccessProdInstService;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneFuncProdInstService;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneMainOfferInstService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.dto.inst.OfferInstDTO;
import com.iwhalecloud.bss.kite.client.dto.inst.ProdInstDTO;
import com.iwhalecloud.bss.kite.client.vo.scene.ProdAttrVO;
import com.iwhalecloud.bss.kite.client.vo.scene.ProdFuncVO;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.dto.ContextDTO;
import com.iwhalecloud.bss.kite.common.unicode.UnicodeServiceOfferKite;
import com.iwhalecloud.bss.kite.common.util.KiteBeanUtils;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.CuccProdAttrVO;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalServiceOfferConsts;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.dataservice.cache.ProductCache;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Offer;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Product;
import com.iwhalecloud.bss.kite.listener.handler.attr.impl.single.IInstConstraintHandler;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttrValue;
import com.iwhalecloud.bss.kite.manager.inst.KiteProdInstFunc;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.manager.inst.change.KiteInstChange;
import com.iwhalecloud.bss.kite.manager.transaction.KiteTransactional;
import com.iwhalecloud.bss.kite.service.scene.attr.OperateInstAttrService;
import com.iwhalecloud.bss.kite.service.util.ProductUtils;
import com.iwhalecloud.bss.kite.web.context.KiteWebContext;
import com.iwhalecloud.bss.kite.web.service.accept.util.AcceptEngineUtil;
import com.iwhalecloud.bss.kite.web.service.accept.util.ProdFuncUtils;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.SpringUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

/** 
 * <Description> 功能产品操作<br> 
 *  
 * @author tengg<br>
 * @version 1.0<br>
 * @taskId <br>
 * @CreateDate 2021年1月4日 <br>
 * @since R9.0<br>
 * @see com.iwhalecloud.bss.kite.cucc.web.controller.scene <br>
 */
@RestController
@RequestMapping("/cuccProdFunc")
@Api(tags = {"/cuccProdFunc - 功能产品"
})
public class CuccProdFuncController {
    
    @Autowired
    IQuerySceneInstService querySceneInstService;
    
    @Autowired
    private IQuerySceneFuncProdInstService querySceneFuncProdInstService;
    
    @Autowired
    private IQuerySceneMainOfferInstService querySceneMainOfferInstService;
    
    @Autowired
    private IQuerySceneAccessProdInstService querySceneAccessProdInstService;
    
    @Autowired
    private IOperateSceneInstService operateSceneInstService;
    
    @Autowired
    private IOperateSceneFuncProdInstService operateSceneFuncProdInstService;
    
    @Autowired
    private OperateInstAttrService operateInstAttrService;
    
    @ApiOperation(value = "查询功能产品属性")
    @ApiImplicitParams({@ApiImplicitParam(name = "prodInstId", value = "功能产品实例标识", required = true)
    })
    @GetMapping(value = "/previewProdFuncAttr")
    public DataResult<List<ProdAttrVO>> qryPreviewProdFuncAttr(@RequestParam String prodInstId) {
        
        ContextDTO context = KiteWebContext.getContext();
        KiteSceneInst kiteSceneInst = querySceneInstService.getSceneInst(context.getCurrentSceneInstId());
        String serviceOfferId = kiteSceneInst.getServiceOfferId();
        KiteProdInstFunc inst = querySceneInstService.getProdInstFunc(context.getCustId(), prodInstId);
        List<KiteAttr> kiteAttrList = inst.listAttrs();
        // 触发onShow方法
        operateInstAttrService.getKiteInstAttrs(inst, kiteAttrList, kiteSceneInst);
        kiteAttrList.removeIf(kiteAttr -> !KiteStringUtils.equalsAny(kiteAttr.getShowType(), KeyConsts.PROD_ATTR_SHOW_TYPE_D, KeyConsts.PROD_ATTR_SHOW_TYPE_M));
        List<ProdAttrVO> cuccProdAttrList = new ArrayList<>();
        if (KiteStringUtils.equalsAny(serviceOfferId, LocalServiceOfferConsts.SERVICE_OFFER_ORDER, UnicodeServiceOfferKite.SEROFF_300000)) {
            kiteAttrList.forEach(funcAttr ->{
                CuccProdAttrVO cuccProdAttrVO = new CuccProdAttrVO();
                KiteBeanUtils.copyProperties(funcAttr, cuccProdAttrVO);
                cuccProdAttrVO.setAttrValueTypeId(LocalKeyConsts.ATTRVALUE_TT);
                cuccProdAttrList.add(cuccProdAttrVO);
            });
        }
        else {
            kiteAttrList.forEach(funcAttr ->{
                CuccProdAttrVO cuccProdAttrVO = new CuccProdAttrVO();
                KiteBeanUtils.copyProperties(funcAttr, cuccProdAttrVO);
                
                if (!KiteStringUtils.isEqual(inst.getActionType().name(), ActionType.D.name()) && !KiteStringUtils.isEqual(cuccProdAttrVO.getValue(), funcAttr.getOriginValue())) {
                    List<KiteAttrValue> staticAttrList = funcAttr.getAttrValues();
                    String oldValueDesc ="";
                    String valuealueDesc ="";
                    if (KiteListUtils.isNotEmpty(staticAttrList)) {
                        KiteAttrValue kiteAttrValue = staticAttrList.stream().filter(attr -> KiteStringUtils.isEqual(attr.getAttrValue(), cuccProdAttrVO.getOldValue())).findFirst().orElse(new KiteAttrValue());
                        oldValueDesc = kiteAttrValue.getAttrValueName();
                        KiteAttrValue kiteAttrValueDesc = staticAttrList.stream().filter(attr -> KiteStringUtils.isEqual(attr.getAttrValue(), cuccProdAttrVO.getValue())).findFirst().orElse(new KiteAttrValue());
                        valuealueDesc = kiteAttrValueDesc.getAttrValueName();
                    }
                    
                    if (KiteStringUtils.isEmpty(oldValueDesc)) {
                        oldValueDesc = cuccProdAttrVO.getOldValue();
                    }
                    if (KiteStringUtils.isNotEmpty(valuealueDesc)) {
                        cuccProdAttrVO.setValueDesc(valuealueDesc);
                    }
                    cuccProdAttrVO.setOldValueDesc(oldValueDesc);
                    cuccProdAttrVO.setChangeFlag(true);
                    cuccProdAttrVO.setNewValue(cuccProdAttrVO.getValue());
                }
                cuccProdAttrVO.setAttrValueTypeId(LocalKeyConsts.ATTRVALUE_TT);
                cuccProdAttrList.add(cuccProdAttrVO);
            });
        }
        return ErrorConsts.SUCCESS.getResult(cuccProdAttrList);
    }
    
    @ApiOperation(value = "查询已经订购功能产品列表")
    @ApiImplicitParams({@ApiImplicitParam(name = "prodInstId", value = "产品实例标识", required = true)
    })
    @GetMapping(value = "/inst")
    public DataResult<List<ProdFuncVO>> listProdInstFunc(@RequestParam String prodInstId) {
        ContextDTO context = KiteWebContext.getContext();

        List<ProdInstDTO> prodFuncInstList = querySceneFuncProdInstService
            .listInUseFuncProdInstByProdInstId(context.getCurrentSceneInstId(), prodInstId, context.getCustId())
            .getResultObject();
        
        ProdInstDTO prodInst = querySceneAccessProdInstService
            .getSceneProdInstByProdInstId(context.getCurrentSceneInstId(), prodInstId, context.getCustId())
            .getResultObject();
        if (KiteListUtils.isEmpty(prodFuncInstList)) {
            dealdelRatePlan(context.getCustId(), context.getCurrentSceneInstId(), prodInst.getProdInstId(), prodFuncInstList);
        }
        // 过滤前台不展示的产品
        prodFuncInstList.removeIf(prodInstDTO -> ProductUtils.isHidden(prodInstDTO.getProdId()));

        if (CollectionUtils.isEmpty(prodFuncInstList)) {
            return ErrorConsts.SUCCESS.getResult(new ArrayList<ProdFuncVO>());
        }
        // 取得产品缺省的功能产品集合
        OfferInstDTO mainOffer = querySceneMainOfferInstService
            .getSceneMainOfferInstByProdInstId(context.getCurrentSceneInstId(), prodInstId, context.getCustId())
            .getResultObject();

        
        String offerId = ProductCache.get(prodInst.getProdId()).getBaseOfferId();
        // 基础销售品没有主套餐
        if (mainOffer != null) {
            offerId = mainOffer.getOfferId();
        }

        Offer offer = OfferCache.get(offerId);
        List<Product> mustFuncList = offer.listMustFuncProds(prodInst.getRoleId(), prodInst.getProdId());

        return ErrorConsts.SUCCESS.getResult(ProdFuncUtils.transformProdFuncList(mustFuncList, prodFuncInstList));
    }
    
    //为了在预览界面查询删除资费计划的详情，特意加了这一段逻辑
    private static void dealdelRatePlan(String custId, String sceneInstId, String prodInstId, List<ProdInstDTO> prodFuncInstList) {
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        List<KiteInstChange> instProdFuncChangeList = querySceneInstService.listInstChanges(sceneInstId, InstType.PROD_INST_FUNC);
        List<KiteProdInstFunc> delFunInstList = Lists.newArrayList();
        KiteProdInstFunc delBaseFunInst = null;
        for (KiteInstChange kiteInstChange : instProdFuncChangeList) {
            if (KiteStringUtils.isEqual(kiteInstChange.getNewValue(),ActionType.D.name())
                && !KiteStringUtils.isEqual(kiteInstChange.getNewValue(),ActionType.A.name())) {
                KiteProdInstFunc delProdFuncInst = querySceneInstService.getProdInstFunc(custId, kiteInstChange.getInstId());
                if (Objects.nonNull(delProdFuncInst)) {
                    if (KiteStringUtils.isNotEmpty(delProdFuncInst.getAccProdInstId())) {
                        if (KiteStringUtils.equals(delProdFuncInst.getAccProdInstId(), prodInstId)) {
                            delBaseFunInst = delProdFuncInst;
                            ProdInstDTO prodInstDto = new ProdInstDTO();
                            KiteBeanUtils.copyProperties(delProdFuncInst, prodInstDto);
                            prodFuncInstList.add(prodInstDto);
                        }
                    }
                    else {
                        delFunInstList.add(delProdFuncInst);
                    }
                }
            }
        }
        if (Objects.nonNull(delBaseFunInst) && KiteListUtils.isNotEmpty(delFunInstList)) {
            // 资费服务 资费计划标识
           KiteAttr rateServiceAttr = delBaseFunInst.getAttrMap().get("200004145");
           if (Objects.isNull(rateServiceAttr)) {
               rateServiceAttr = delBaseFunInst.getAttrMap().get("200004129");
           }
           if (Objects.isNull(rateServiceAttr)) {
               rateServiceAttr = delBaseFunInst.getAttrMap().get("200004146");
           }
           for (KiteProdInstFunc delFunInst : delFunInstList) {
               KiteAttr rateBaseAttr = delFunInst.getAttrMap().get("200004129");
               KiteAttr rateDiscAttr = delFunInst.getAttrMap().get("200004146");
               KiteAttr rateServAttr = delFunInst.getAttrMap().get("200004145");
               if ((Objects.nonNull(rateBaseAttr) && KiteStringUtils.equals(rateServiceAttr.getValue(), rateBaseAttr.getValue()))
                   || (Objects.nonNull(rateDiscAttr) && KiteStringUtils.equals(rateServiceAttr.getValue(), rateDiscAttr.getValue()))
                   || (Objects.nonNull(rateServAttr) && KiteStringUtils.equals(rateServiceAttr.getValue(), rateServAttr.getValue()))) {
                   delFunInst.setAccProdInstId(delBaseFunInst.getAccProdInstId());
                   ProdInstDTO prodInstDto = new ProdInstDTO();
                   KiteBeanUtils.copyProperties(delFunInst, prodInstDto);
                   prodFuncInstList.add(prodInstDto);
               }
                   
           }
        }
    }
    
    @KiteTransactional
    @ApiOperation(value = "添加功能产品", notes = "赋值新增功能产品，将原功能产品的属性设置为新功能产品的属性")
    @ApiImplicitParams({@ApiImplicitParam(name = "prodInstId", value = "功能产品实例标识", required = true)
    })
    @PostMapping
    public DataResult<ProdFuncVO> copuSaveProdFunc(@RequestParam String prodInstId) {
        String staffId = KiteStringUtils.valueOf(ContextUtil.getUserId());
        String sceneInstId = KiteWebContext.getContext().getCurrentSceneInstId();
        String custId = KiteWebContext.getContext().getCustId();
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        KiteProdInstFunc prodInstFunc = querySceneInstService.getKiteInst(custId, InstType.PROD_INST_FUNC, prodInstId);
        List<KiteAttr> kiteAttrList = prodInstFunc.listAttrs();
        operateSceneInstService.putExtParameter(sceneInstId, IInstConstraintHandler.KEY_IF_EXECUTE, Boolean.TRUE);
        DataResult<ProdFuncVO> result = operateSceneFuncProdInstService
            .addFuncProdInst(sceneInstId, prodInstFunc.getAccProdInstId(), prodInstFunc.getProdId(), custId, staffId);
        KiteProdInstFunc newProdInstFunc = this.querySceneInstService.getProdInstFunc(custId, result.getResultObject().getProdInstId());
        kiteAttrList.stream().forEach(kiteAttr ->{
            operateInstAttrService.setAttrValue(newProdInstFunc, kiteAttr.getFieldName(), kiteAttr.getValue(), sceneInstId, null);
        });
        
        AcceptEngineUtil.refreshScene(result);
        return result;
    }
}
